﻿using System;

namespace Algoritmia.Problems.Geometry
{
    public class Point2D : IComparable<Point2D>,
        IEquatable<Point2D>
    {
        public double X;
        public double Y;

        public Point2D(Tuple<double,double> elem)
        {
            X = elem.Item1;
            Y = elem.Item2;
        }
        public Point2D(double x, double y)
        {
            X = x;
            Y = y;
        }

        #region Implementation of IComparable<in Point2D>

        public int CompareTo(Point2D other)
        {
            if (X == other.X)
            {
                return Y.CompareTo(other.Y);
            }
            return X < other.X ? -1 : 1;
        }

        #endregion

        public override bool Equals(object obj)
        {
            if ( obj is Point2D)
            {
                var arg = (Point2D) obj;
                return arg.X == X && arg.Y == Y;
            }
            return false;
        }

        public override int GetHashCode()
        {
            return X.GetHashCode() + Y.GetHashCode();
        }

        public bool Equals(Point2D other)
        {
            return other.X == X && other.Y == Y;
        }

        public override string ToString()
        {
            return "Point2D(" + X + ";" + Y + ")";
        }

    }

    public static class Utils
    {
        public static double EuclideanDistance(Point2D a, Point2D b)
        {
            double x = a.X - b.X;
            double y = a.Y - b.Y;
            return Math.Sqrt(x*x + y*y);
        }

        public static bool Left(Point2D a, Point2D b, Point2D c)
        {
            return (a.Y - b.Y) * (c.X - b.X) - (a.X - b.X) * (c.Y - b.Y) > 0;
        }

        public static bool Right(Point2D a, Point2D b, Point2D c)
        {
            return ( a.Y - b.Y) * (c.X - b.X) - (a.X - b.X) * (c.Y - b.Y) < 0;
        }

        public static double TriangleArea(Point2D a, Point2D b, Point2D c)
        {
            return Math.Abs((a.Y - b.Y) * (c.X - b.X) - (a.X - b.X) * (c.Y - b.Y)) / 2;
        }
    }

}